#!/usr/bin/python
# -*- coding:UTF-8 -*-
from main import *
import unittest

gs.USE_GRAPHICS = False

class TestUtilityFunctions(unittest.TestCase):
    def test_game_settings(self):
        GameSettings = Settings()
        self.assertEqual(GameSettings.this_property_does_not_exist,None)
        GameSettings.property = 3
        self.assertEqual(GameSettings.property, 3)
        GameSettings.property = 5
        self.assertEqual(GameSettings.property, 5)

class TestDeck(unittest.TestCase):
    def setUp(self):
        gs.visual_system = VisualSystem(gs)
        Card.names_already_used.clear()
        self.chars, self.modifiers, self.deaths = create_dummy_cards()
        self.all_cards = self.deaths + self.modifiers
        self.deck = Deck()
        self.player = Player("Test Test")

    def populate_deck(self):
        for card in self.all_cards:
            self.deck.add_card(card)

    def test_add_card(self):
        self.populate_deck()

        # draw every card
        for x in range(len(self.deck.cards)):
            self.player.draw_card()
            self.assertEqual(len(self.deck.cards) + len(self.player.cards), len(self.all_cards))

        # return every card
        while len(self.player.cards) > 0:
            self.player.discard_card(0)
            self.assertEqual(len(self.deck.discarded_cards) + len(self.deck.cards) + len(self.player.cards), len(self.all_cards))

    def test_reset_deck(self):
        self.populate_deck()        

        # draw every card
        for x in range(len(self.deck.cards)):
            self.player.draw_card()

        # return every card
        while len(self.player.cards) > 0:
            self.player.discard_card(0)

        # draw every card again
        # This causes the deck to reset
        for x in range(len(self.all_cards)):
            self.player.draw_card()
            self.assertEqual(len(self.deck.discarded_cards) + len(self.deck.cards) + len(self.player.cards), len(self.all_cards))

    def test_run_out_of_cards(self):
        self.populate_deck()

        for x in range(len(self.all_cards)):
            self.player.draw_card()

        self.assertRaises(AssertionError, self.player.draw_card)

class TestCards(unittest.TestCase):
    def setUp(self):
        gs.visual_system = VisualSystem(gs)
        Card.names_already_used.clear()
        self.player = Player("Test Test")
        self.character = Character("Test")
        self.modifier = Modifier("Test2", [10,-5,0])
        self.modifier2 = Modifier("Test3", [-20,None,None], (lambda card, player: (card, player)))
        self.death = UntimelyDeath("Test4", [None,None,None])

    def test_cards_are_unique(self):
        mod3 = Modifier("Test_1", [10,-5,0])
        self.assertRaises(AssertionError, Modifier, "Test_1", [10,-5,0])

    def test_take_character(self):
        self.assertRaises(AssertionError, self.player.take_card, self.character)
        
    def test_take_card(self):
        num_cards = len(self.player.cards)
        self.player.take_card(self.modifier)
        self.assertEqual(num_cards + 1, len(self.player.cards))
        self.assertTrue(self.modifier in self.player.cards)
        self.assertTrue(self.modifier.player == self.player)

    def test_discard_card(self):
        num_cards = len(self.player.cards)
        self.player.take_card(self.modifier)
        self.assertEqual(num_cards + 1, len(self.player.cards))
        self.player.discard_card(card = self.modifier)
        
        self.assertEqual(num_cards, len(self.player.cards))

    def test_place_modifier(self):
        self.player.take_card(self.modifier)
        self.player.place_card(self.modifier,self.character)
        self.assertEqual(self.character.modifiers, [10,-5,0])   
    
    def test_remove_modifier(self):
        self.player.take_card(self.modifier)
        self.player.place_card(self.modifier,self.character)
        self.assertEqual(self.character.modifiers, [10,-5,0])
        self.character.remove_top_card()
        self.assertEqual(self.character.modifiers, [0,0,0])

    def test_stack_modifiers(self):
        self.player.take_card(self.modifier)
        self.player.take_card(self.modifier2)

        self.player.place_card(self.modifier,self.character)
        self.player.place_card(self.modifier2,self.character)
        self.assertEqual(self.character.modifiers, [-20,-5,0])

        self.character.remove_top_card()
        self.assertEqual(self.character.modifiers, [10,-5,0])

class TestPlayer(unittest.TestCase):
    def setUp(self):
        Card.names_already_used.clear()
        self.chars, self.modifiers, self.deaths = create_dummy_cards()
        self.all_cards = self.deaths + self.modifiers
        self.deck = Deck()
        self.player = Player("Test Test")

    def populate_deck(self):
        for card in self.all_cards:
            self.deck.add_card(card)

    def test_improper_kill_with_positive_self_worth(self):
        self.player.characters.append(self.chars[0])
        for d in self.deaths:
            self.deck.add_card(d)
        card = self.player.draw_card()
        self.assertRaises(AssertionError, self.player.place_card, card, self.player.characters[0])

unittest.main()
